import sys
import pygame


from time import sleep
from game_stats import GameStats
from settings import Settings
from ship import Ship
from bullet import Bullet
from alien import Alien
from scoreboard import Scoreboard

from button import Button

import random


class AlienInvasion:
    """管理游戏资源和⾏为的类"""

    def __init__(self):
        """初始化游戏并创建游戏资源"""
        pygame.init()
        self.settings = Settings()
        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height)
        )

        # 全屏设置
        # self.screen = pygame.display.set_mode((0, 0),pygame.FULLSCREEN)
        # self.settings.screen_width = self.screen.get_rect().width
        # self.settings.screen_height = self.screen.get_rect().height

        pygame.display.set_caption("Alien Invasion")

        # 创建存储游戏统计信息的实例，并创建记分牌
        self.stats = GameStats(self)
        self.sb = Scoreboard(self)

        self.ship = Ship(self)
        self.clock = pygame.time.Clock()

        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

        # 游戏启动后处于活动状态
        self.game_active = False

        # 创建 Play 按钮
        self.play_button = Button(self, "Play")

    def run_game(self):
        """开始游戏的主循环"""
        while True:
            # 侦听键盘和⿏标事件
            self._check_events()

            if self.game_active:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()

            self._update_screen()

    def _create_fleet(self):
        """创建⼀个外星舰队"""
        # 创建⼀个外星⼈，再不断添加，直到没有空间添加外星⼈为⽌
        # 外星⼈的间距为外星⼈的宽度
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        current_x, current_y = alien_width, alien_height

        """生成铺满屏幕"""
        # while current_y < (self.settings.screen_height - 3 * alien_height):
        #     while current_x < (self.settings.screen_width - 2 * alien_width):
        #         self._create_alien(current_x, current_y)
        #         current_x += 2 * alien_width
        #         # 添加⼀⾏外星⼈后，重置 x 值并递增 y 值
        #     current_x = alien_width
        #     current_y += 2 * alien_height

        """随机生成不重叠的"""

        for x in range(self.settings.alien_init_num):
            current_y = random.randrange(
                alien_height,
                self.settings.screen_height - 4 * alien_height,
                2 * alien_height,
            )
            current_x = random.randrange(
                alien_height,
                self.settings.screen_width - 2 * alien_width,
                2 * alien_width,
            )
            self._create_alien(current_x, current_y)

    def _create_alien(self, x_position, y_position):
        """创建⼀个外星⼈并将其放在当前⾏中"""
        new_alien = Alien(self)
        new_alien.x = x_position
        new_alien.y = y_position
        new_alien.rect.x = x_position
        new_alien.rect.y = y_position
        self.aliens.add(new_alien)

    def _check_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)

            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)

    def _check_play_button(self, mouse_pos):
        """在玩家单击 Play 按钮时开始新游戏"""
        if self.play_button.rect.collidepoint(mouse_pos) and not self.game_active:
            # 还原游戏设置
            self.settings.initialize_dynamic_settings()
            self.stats.reset_stats()
            self.sb.prep_score()
            self._start_game()
    
    def _start_game(self):

        # 重置游戏的统计信息
        self.stats.reset_stats()
        self.game_active = True
        # 清空外星⼈列表和⼦弹列表
        self.bullets.empty()
        self.aliens.empty()
        # 创建⼀个新的外星舰队，并将⻜船放在屏幕底部的中央
        self._create_fleet()
        self.ship.center_ship()

        # 隐藏光标
        pygame.mouse.set_visible(False)


    def _check_keydown_events(self, event):
        if event.key == pygame.K_RIGHT:
            # 向右移动⻜船
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            # 向左移动⻜船
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()
        elif event.key == pygame.K_p:
            # 还原游戏设置
            self.settings.initialize_dynamic_settings()
            self._start_game()

    def _fire_bullet(self):
        """创建⼀颗⼦弹，并将其加⼊编组 bullets"""
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _check_keyup_events(self, event):
        if event.key == pygame.K_RIGHT:
            # 停止向右移动⻜船
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            # 停止向左移动⻜船
            self.ship.moving_left = False

    def _update_bullets(self):
        self.bullets.update()
        # 绘制子弹，并且删除越界子弹
        for bullet in self.bullets.sprites():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)
                print(len(self.bullets))
                if not self.bullets:
                    # 三次未击中⽬标时结束游戏
                    if(self.stats.kill_count == 0):
                        self.game_active = False

        self._check_bullet_alien_collisions()

    def _check_bullet_alien_collisions(self):
        # 检查是否有⼦弹击中了外星⼈
        # 如果是，就删除相应的⼦弹和外星⼈
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)

        if collisions: 
            for aliens in collisions.values():
                self.stats.score += self.settings.alien_points * len(aliens)

                # 击中则计数加一
                self.stats.kill_count += 1
                
            self.sb.prep_score()
            self.sb.check_high_score()


        if not self.aliens:
            # 删除现有的⼦弹并创建⼀个新的外星舰队
            self.bullets.empty()
            self._create_fleet()
            self.settings.increase_speed()



    def _update_aliens(self):
        """检查是否有外星⼈位于屏幕边缘，并更新整个外星舰队的位置"""
        self._check_fleet_edges()
        self.aliens.update()
        # 检测外星⼈和⻜船之间的碰撞
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()


    def _check_aliens_bottom(self):
        """检查是否有外星⼈到达了屏幕的下边缘"""
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= self.settings.screen_height:
                # 像⻜船被撞到⼀样进⾏处理
                self._ship_hit()
                break
        # 检查是否有外星⼈到达了屏幕的下边缘
        self._check_aliens_bottom()
    
    def _ship_hit(self):
        """响应⻜船和外星⼈的碰撞"""
        if self.stats.ships_left > 0:
            # 将 ships_left 减 
            self.stats.ships_left -= 1
            # 清空外星⼈列表和⼦弹列表
            self.bullets.empty()
            self.aliens.empty()
            # 创建⼀个新的外星舰队，并将⻜船放在屏幕底部的中央
            self._create_fleet()
            self.ship.center_ship()
              # 暂停
            sleep(0.5)
        else:
            self.game_active = False
      

    def _check_fleet_edges(self):
        """在有外星⼈到达边缘时采取相应的措施"""
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """将整个外星舰队向下移动，并改变它们的⽅向"""
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _update_screen(self):
        # 让最近绘制的屏幕可⻅
        self.screen.fill(self.settings.bg_color)

        for bullet in self.bullets.sprites():
            bullet.draw_bullet()

        self.ship.blitme()

        self.aliens.draw(self.screen)

        # 显⽰得分
        self.sb.show_score()

        # 如果游戏处于⾮活动状态，就绘制 Play 按钮
        if not self.game_active:
            self.play_button.draw_button()

        pygame.display.flip()
        self.clock.tick(60)


if __name__ == "__main__":
    # 创建游戏实例并运⾏游戏
    ai = AlienInvasion()
    ai.run_game()
